/*!
 *  @file       led_driver.h
 *  @brief      led driver harder file 
 *  @author     T4056 Student
 *  @date       2024-07-20
 *  @version    V1.0
 *  @par        Copyright(c):
 *              T4056 Student.All rights reserved. 
 */
#ifndef _led_driver_h_
#define _led_driver_h_

#include <stdlib.h>
#include <string.h>

#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_gpio.h"

/*!
 *	@brief		struct of pin attribute
 *	@details	name port num state mode pull init
 *	@note		All GPIO pins should be defined here, including LED, KEY
 */
typedef enum
{
	PIN_TYPE_BLUE = 0,		/**< PIN LED  */
	PIN_TYPE_MAX,			/**< PIN MAX NUM */
}pin_type_e;

/*!
 *	@brief		struct of pin attribute
 *	@details	name port num state mode pull init
 */
typedef struct
{
	char * name;			/**< pin name */
	GPIO_TypeDef * port;	/**< pin port,it can be ignored to save space */
	uint16_t pin;			/**< pin num,it can be ignored to save space */
	GPIO_PinState state;	/**< pin state */
	uint32_t mode;			/**< pin mode,for add _set_mode and _get_mode functions the next version */
	uint32_t pull;			/**< pin pull,for add _set_pull and _get_pull functions the next version */
	uint8_t init;			/**< pin init */
}pin_attr_t;

/*!
 *	@brief		struct of pin driver
 *	@details	pin attributes and pin oprations
 */
typedef struct
{
	pin_attr_t pin_attr[PIN_TYPE_MAX];		/**< pin attribute for all pin */
	struct pin_driver_ops * ops;			/**< pin driver opration awalys is that */
}pin_driver_t;

/*!
 *	@brief 		struct of pin driver oprations
 *	@details	init set_state get_state toggle
 *	@todo		add function _set_mode _get_mode _set_pull _set_pull		
 */
typedef struct pin_driver_ops
{
	int (* pf_init)(		pin_driver_t * me,
							pin_type_e pin_type);					

	int (* pf_set_state)(	pin_driver_t * me,
							pin_type_e pin_type,
							GPIO_PinState state);

	int (* pf_get_state)(	pin_driver_t * me,
							pin_type_e pin_type,
							GPIO_PinState * state);

	int (* pf_toggle)(		pin_driver_t * me,
							pin_type_e pin_type);

}pin_driver_ops_t;

/*!
 *	@brief		pin driver register
 *	@param		me
 *	@param		pin_type
 *	@param		pin_name
 *	@return		0:register success!
 *				1:register failure,the wrong is pin name's length
 */
int pin_driver_register(pin_driver_t * me,pin_type_e pin_type,const char * pin_name);

#endif
